import { Alert, Tabs, TabItem } from '@aws-amplify/ui-react'; import { Example, ExampleCode } from '@/components/Example'; import { DefaultDarkMode, SystemDarkModeExample, CustomDarkModeExample, } from './examples'; ## Overview Amplify UI supports color modes/schemes, like Dark Mode, through theme overrides. Amplify UI Theme Overrides let you define different theme styles in different contexts, such as color mode. You can also use plain CSS. There are 2 ways to support light/dark mode in your application: 1. Rely on the user's OS preference (_System Preferences > General > Appearance in Mac_) 2. Place a control like a toggle button in your application that allows the user to switch color modes. With this option you could default to the OS preference or show 3 options: light, dark, system, like this site does. Either of these approaches work with Amplify UI whether you are using the Theme Overrides or writing plain CSS. ## ThemeProvider ### colorMode The `ThemeProvider` accepts a `colorMode` prop which can be `light`, `dark`, or `system`. If you have multiple `ThemeProvider`s in your application, make sure to store `colorMode` in the application's state or context and pass it to each `ThemeProvider` or else some parts of your app won't have the right color mode applied. Also, because the theme uses CSS variables which are inherited, your application can have some weird behavior with nested themes and color modes. Multiple `ThemeProvider`s should be avoided if possible because it is more efficient to use a selector override instead. This site uses nested `ThemeProvider`s for demos. ### Default Dark Mode Amplify UI comes with a default dark mode that you can use. _Note: the Amplify UI theme and any overrides like dark mode are scoped to the ThemeProvider. Changing the color mode in the example will only affect the example code._ ```jsx import * as React from 'react'; import { defaultDarkModeOverride, ThemeProvider, Card, Text, ToggleButton, ToggleButtonGroup, } from '@aws-amplify/ui-react'; export const DefaultDarkMode = () => { const [colorMode, setColorMode] = React.useState('system'); const theme = { name: 'my-theme', overrides: [defaultDarkModeOverride], }; return ( setColorMode(value)} > Light Dark System Current color mode: {colorMode} ); }; ``` ```tsx file=./examples/DefaultDarkMode.tsx ``` ### System Dark Mode If you don't want to provide a color mode control on your application, but still want to honor the user's operating system preference for color mode, you can set the `colorMode` on the ThemeProvider to `system`. Then use either the default dark mode override styling or provide your own. _Note: to see dark mode applied, change your OS preferences_ ```tsx file=./examples/SystemDarkMode.tsx ``` ### Custom dark mode ```jsx import * as React from 'react'; import { ThemeProvider, Card, Text, ToggleButton, ToggleButtonGroup, } from '@aws-amplify/ui-react'; export const CustomDarkModeExample = () => { const [colorMode, setColorMode] = React.useState('system'); const theme = { name: 'my-theme', overrides: [ { colorMode: 'dark', tokens: { colors: { font: { primary: { value: '{colors.pink.100}' }, secondary: { value: '{colors.pink.90}' }, tertiary: { value: '{colors.pink.80}' }, }, background: { primary: { value: '{colors.purple.10}' }, secondary: { value: '{colors.purple.20}' }, tertiary: { value: '{colors.purple.40}' }, }, border: { primary: { value: '{colors.pink.60}' }, secondary: { value: '{colors.pink.40}' }, tertiary: { value: '{colors.pink.20}' }, }, }, }, }, ], }; return ( // Note: color mode overrides are scoped to the ThemeProvider // if you use multiple providers setColorMode(value)} > Light Dark System Current color mode: {colorMode} ); }; ``` ```tsx file=./examples/CustomDarkMode.tsx ``` ## CSS You can also write CSS variables directly to support color modes. If you are using the `colorMode` prop in the `ThemeProvider`, you can write CSS like this to support dark mode: ```css /* The prefers-color-scheme media query detects the system setting */ @media (prefers-color-scheme: dark) { [data-amplify-color-mode='system'] { --amplify-colors-background-primary: black; } } [data-amplify-color-mode='dark'] { --amplify-colors-background-primary: black; } ```